package com.jhc.common.core.dict;

import cn.hutool.core.util.EnumUtil;
import com.jhc.api.base.DictData;
import org.reflections.Reflections;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.MultiValueMap;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class DictScanner implements ImportBeanDefinitionRegistrar {
    public static String scanPackage = null;

    /**
     * 获取Spring中DictScan注解上的扫描路径
     *
     * @param importingClassMetadata
     * @param registry
     * @param importBeanNameGenerator
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
        MultiValueMap<String, Object> allAnnotationAttributes = importingClassMetadata.getAllAnnotationAttributes(DictScan.class.getName());
        List<Object> value = allAnnotationAttributes.get("value");
        DictScanner.scanPackage = (String) value.get(0);
    }


    /**
     * 获取路径下所有被DictData注解的枚举类
     *
     * @param packageName 包路径
     * @return
     */
    public static List<Map<String, Object>> scanEnums(String packageName) {
        Reflections reflections = new Reflections(packageName);
        return doScan(reflections);
    }

    /**
     * 默认扫描所有路径
     *
     * @return
     */
    public static List<Map<String, Object>> scanEnums() {
        Reflections reflections;
        if (scanPackage == null) {
            reflections = new Reflections();
        } else {
            reflections = new Reflections(scanPackage);
        }
        return doScan(reflections);
    }

    private static List<Map<String, Object>> doScan(Reflections reflections) {
        // 扫描包内所有带DictData的枚举
        Set<Class<?>> enums = reflections.getTypesAnnotatedWith(DictData.class);
        return enums.stream().map((clz) -> {
            Map<String, Object> map = new HashMap<>();
            map.put("code", clz.getSimpleName());
            // 枚举类型中text字段作为name
            EnumUtil.getNameFieldMap((Class<? extends Enum<?>>) clz, clz.getAnnotation(DictData.class).textFiled())
                    .forEach((k, v) ->
                            map.put("dataList", new HashMap<String, Object>() {{
                                put("code", k);
                                put("text", v.toString());
                            }})
                    );
            return map;
        }).collect(Collectors.toList());
    }
}
